package com.imooc.article.controller;

import com.imooc.api.BaseController;
import com.imooc.api.controller.article.ArticlePortalControllerApi;
import com.imooc.article.service.ArticlePortalService;
import com.imooc.grace.result.GraceJSONResult;
import com.imooc.pojo.Article;
import com.imooc.pojo.vo.AppUserVO;
import com.imooc.pojo.vo.ArticleDetailVO;
import com.imooc.pojo.vo.IndexArticleVO;
import com.imooc.utils.IPUtil;
import com.imooc.utils.PagedGridResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

@RestController
public class ArticlePortalController extends BaseController implements ArticlePortalControllerApi {

    @Autowired
    private ArticlePortalService articlePortalService;

    /**
     * 首页查询文章列表（后续的搜索接口）
     *
     * @param keyword  搜索关键字
     * @param category 文章分类
     */
    @Override
    public GraceJSONResult list(String keyword, Integer category, Integer page, Integer pageSize) {
        if (page == null) {
            page = COMMON_START_PAGE;
        }
        if (pageSize == null) {
            pageSize = COMMON_PAGE_SIZE;
        }
        PagedGridResult gridResult = this.articlePortalService.queryIndexArticleList(keyword, category, page, pageSize);
        // 将文章信息和文章所属作者信息合并
        rebuildArticleGrid(gridResult);
        return GraceJSONResult.ok(gridResult);
    }

    /**
     * 首页查询热闻列表
     */
    @Override
    public GraceJSONResult hotList() {
        return GraceJSONResult.ok(this.articlePortalService.queryHotList());
    }

    /**
     * 查询作家发布的所有文章列表
     */
    @Override
    public GraceJSONResult queryArticleListOfWriter(String writerId, Integer page, Integer pageSize) {
        if (page == null) {
            page = COMMON_START_PAGE;
        }
        if (pageSize == null) {
            pageSize = COMMON_PAGE_SIZE;
        }
        PagedGridResult gridResult = this.articlePortalService.queryArticleListOfWriter(writerId, page, pageSize);
        // 将文章信息和文章所属作者信息合并
        rebuildArticleGrid(gridResult);
        return GraceJSONResult.ok(gridResult);
    }

    /**
     * 作家页面查询近期佳文
     */
    @Override
    public GraceJSONResult queryGoodArticleListOfWriter(String writerId) {
        PagedGridResult gridResult = this.articlePortalService.queryGoodArticleListOfWriter(writerId);
        return GraceJSONResult.ok(gridResult);
    }

    /**
     * 文章详情查询
     */
    @Override
    public GraceJSONResult detail(String articleId) {
        // 查询文章的详情
        ArticleDetailVO detailVO = this.articlePortalService.queryDetail(articleId);

        // 获取文章作者信息
        HashSet<String> idSet = new HashSet<>();
        idSet.add(detailVO.getPublishUserId());
        List<AppUserVO> publisherList = getBasicUserList(idSet);
        if (!publisherList.isEmpty()) {
            detailVO.setPublishUserName(publisherList.get(0).getNickname());
        }

        // 设置文章的阅读数
        detailVO.setReadCounts(getCountsFromRedis(REDIS_ARTICLE_READ_COUNTS + ":" + articleId));
        return GraceJSONResult.ok(detailVO);
    }

    /**
     * 阅读文章，文章阅读量累加
     */
    @Override
    public GraceJSONResult readArticle(String articleId, HttpServletRequest request) {
        // 整个方法通过拦截器，进行阅读数防刷的

        // 获取用户的ip
        String userIp = IPUtil.getRequestIp(request);
        // 设置针对当前用户ip的永久存在的key，存入到redis，表示该ip的用户已经阅读过了，无法累加阅读量
        redis.setnx(REDIS_ALREADY_READ + ":" + articleId + ":" + userIp, userIp);
        // 阅读数累加+1
        redis.increment(REDIS_ARTICLE_READ_COUNTS + ":" + articleId, 1);
        return GraceJSONResult.ok();
    }

    /**
     * 将文章信息和文章所属作者信息合并
     */
    private void rebuildArticleGrid(PagedGridResult gridResult) {
        // 获取文章信息
        List<Article> list = (List<Article>) gridResult.getRows();

        // 构建发布者id列表，构建文章id的list
        HashSet<String> idSet = new HashSet<>();
        List<String> idList = new ArrayList<>();

        for (Article article : list) {
            // 构建发布者的set
            idSet.add(article.getPublishUserId());
            // 构建文章id的list
            idList.add(REDIS_ARTICLE_READ_COUNTS + ":" + article.getId());
        }

        // 发起redis的mget批量查询api，批量获取这些文档的阅读数
        List<String> readCountsRedisList = redis.mget(idList);

        // 发起远程调用，请求用户服务获得文章作者信息
        List<AppUserVO> publisherList = getBasicUserList(idSet);

        // 拼接两个list，重组文章列表
        List<IndexArticleVO> indexArticleList = new ArrayList<>();

        // 遍历原本的文章信息列表，将文章所属的作者信息合在一起
        for (int i = 0; i < list.size(); i++) {
            IndexArticleVO indexArticleVO = new IndexArticleVO();
            Article article = list.get(i);
            BeanUtils.copyProperties(article, indexArticleVO);

            // 从publisherList中获得发布者的基本信息
            AppUserVO publisher = getUserIfPublisher(article.getPublishUserId(), publisherList);
            indexArticleVO.setPublisherVO(publisher);

            // 重新组装设置文章列表中的阅读量
            String redisCountsStr = readCountsRedisList.get(i);
            int readCounts = 0;
            if (StringUtils.isNotBlank(redisCountsStr)) {
                readCounts = Integer.parseInt(redisCountsStr);
            }
            indexArticleVO.setReadCounts(readCounts);

            // 将新的文章和作者信息添加到集合中
            indexArticleList.add(indexArticleVO);
        }

        gridResult.setRows(indexArticleList);
    }

    /**
     * 通过文章表中的作者id，遍历查找作者信息
     */
    private AppUserVO getUserIfPublisher(String publisherId, List<AppUserVO> publisherList) {
        for (AppUserVO user : publisherList) {
            if (user.getId().equalsIgnoreCase(publisherId)) {
                return user;
            }
        }
        return null;
    }
}
